perm filename TALK11.SAI[PNT,HE]3 blob
sn#492443 filedate 1980-01-22 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00007 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00002 00002 ENTRY
C00004 00003 ! PEEK, POKE, STRT11,PEEKARRAY, POKEARRAY
C00009 00004 ! check elf status and communication
C00013 00005 ! routines that make console look like VT05
C00018 00006 ! alinit
C00020 00007 ! sav11,res11
C00022 ENDMK
C⊗;
ENTRY;
BEGIN
DEFINE $TALK11=TRUE;
REQUIRE "HEADER.SAI" SOURCE_FILE;
! DEFINE OUTTST = "OUTSTR";
DEFINE OUTTST = "! ";
INTEGER ELFCHAN; ! Channel number for I/O to ELF;
PROCEDURE COMERR
(STRING MESSG;RECORD_POINTER(ANY_CLASS) CONTXT (NULL_RECORD));
! Non-fatal warnings;
BEGIN
USERERR(0,1,"HAH! "&MESSG);
END;
DEFINE SGNEXT="'4000000"; ! extend sign bit of input data ;
DEFINE OWPW ="0"; ! word for word transfer;
DEFINE TWRJ ="'1000000"; ! two words per word,right justified in each halfword;
DEFINE TWRM ="'2000000"; ! two words per word,in right most 32 bits;
DEFINE TWLM ="'3000000"; ! two words per word,in left most 32 bits;
integer array ttmpbuf[1:fbuffsiz*2];
DEFINE ELFHIADDR="('500000)";
! PEEK, POKE, STRT11,PEEKARRAY, POKEARRAY;
INTEGER MTAPE_PLUS_ELF;
DEFINE ELFMTAPE(ADDR)="CODE(MTAPE_PLUS_ELF,ADDR)";
! peek,poke and peekarray take the actual address on the unibus;
PROCEDURE FILL(INTEGER ADR(0),LEN(ELFHIADDR/2),CNTNTS(0));
BEGIN "fill"
INTEGER ARRAY A[1:2];
DEFINE FILL = "'001000000000";
A[1]←FILL+(ADR LSH -1);
A[2]←(LEN LSH 18)+CNTNTS;
ELFMTAPE(A[1]);
IF NOT _SKIP_ THEN COMERR("Couldn't fill ELF with "&CVOS(CNTNTS));
END;
INTERNAL INTEGER PROCEDURE PEEK(INTEGER ADR);
BEGIN "peek" ! Returns the ELF word at unibus address ADR;
INTEGER ARRAY A[1:2];
DEFINE PEEK = "'002000000000";
A[1]←PEEK+(ADR LSH -1);
! CALLU0("MTAPE",ELFCHAN,A[1]);
ELFMTAPE(A[1]);
IF NOT _SKIP_ THEN COMERR("Couldn't peek at ELF");
RETURN(A[2]);
END "peek";
PROCEDURE POKE(INTEGER ADR, CONTENTS);
BEGIN "poke" ! Stores CONTENTS at unibus address ADR;
DEFINE POKE = "'003000000000";
INTEGER ARRAY A[1:2];
A[1]←POKE+(ADR LSH -1);
A[2]←CONTENTS;
! CALLU0("MTAPE",ELFCHAN,A[1]);
ELFMTAPE(A[1]);
IF NOT _SKIP_ THEN COMERR("Couldn't poke at ELF");
END "poke";
PROCEDURE STRT11(INTEGER STRADR('1000));
BEGIN "strt11" ! Starts 11 at STRADR;
DEFINE START = "'005000000000";
INTEGER ARRAY A[1:2];
INTEGER NOSTART;
NOSTART←PEEK(NOSTRT);
IF NOSTART THEN BEGIN
POKE(NOSTRT,0); PRINT("Did not restart ELF");
RETURN;
END;
A[1]←START;
A[2]←0;
POKE('24,STRADR); ! set starting address;
POKE('26,'340); ! set priority level 7;
! CALLU0("MTAPE",ELFCHAN,A[1]);
ELFMTAPE(A[1]);
IF NOT _SKIP_ THEN COMERR("Couldn't start ELF");
CALL(5,"SLEEP"); ! go sleep fro 5 seconds;
END "strt11";
INTERNAL PROCEDURE POKEARRAY(INTEGER ADR, LTH; INTEGER ARRAY CONTENTS; INTEGER USETBITS(0));
BEGIN "pokearray" ! Sends the CONTENTS[1:LTH] to unibus address ADR
and higher;
INTEGER USETO_WORD,SNDIOWD;
USETO_WORD←'400000400000 + (ADR LSH -1)+USETBITS;
CALLU0("USETO",ELFCHAN,USETO_WORD);
SNDIOWD←IOWD(LTH,LOCATION(CONTENTS[1]));
CALLU0("OUT",ELFCHAN,SNDIOWD);
IF _SKIP_ THEN COMERR("POKEARRAY failed");
END "pokearray";
INTERNAL PROCEDURE PEEKARRAY(INTEGER ADR, LTH; INTEGER ARRAY CONTENTS; INTEGER USETBITS(0));
BEGIN "peekarray" ! Gets the CONTENTS[1:LTH] from unibus address ADR
and higher;
INTEGER USETI_WORD,GETIOWD;
USETI_WORD←'400000400000 +(ADR LSH -1)+USETBITS;
CALLU0("USETI",ELFCHAN,USETI_WORD);
GETIOWD←IOWD(LTH,LOCATION(CONTENTS[1]));
CALLU0("IN",ELFCHAN,GETIOWD);
IF _SKIP_ THEN COMERR("PEEKARRAY failed");
END "peekarray";
! check elf status and communication ;
INTEGER PROCEDURE ELFSTATUS;
BEGIN
INTEGER I,STATUS;
CHKESC_I;
POKE(NOTB11,WAKEUP);
FOR I←1 STEP 1 UNTIL 10 DO
BEGIN
URSCHD;
CALL(0,"SLEEP");
STATUS←PEEK(NOTB11);
IF STATUS≠ASLEEP THEN RETURN(STATUS);
END;
RETURN(STATUS);
END;
BOOLEAN ELF_ASLEEP_PRINTED;
INTEGER PROCEDURE LISTENELF;
BEGIN
INTEGER STATUS;
$ELFABORTED←FALSE;
STATUS←ELFSTATUS;
IF STATUS≠ASLEEP THEN RETURN(STATUS);
IF NOT ELF_ASLEEP_PRINTED THEN
BEGIN
PRINT("ELF is asleep, I will keep trying to wake it",CRLF,
" till you type esc_I to abort",CRLF);
ELF_ASLEEP_PRINTED←TRUE;
END;
DO BEGIN
STATUS←ELFSTATUS;
CHKESC_I;
END UNTIL STATUS≠ASLEEP;
RETURN(STATUS);
END;
INTERNAL PROCEDURE EVAL(RPTR(EXPR$) EE);
BEGIN
INTEGER I,PSIZE;
$PCDMAX←$PCDMAX MAX (PSIZE←EXPR$:#BODY[EE]);
IF $NOELF OR $ELFUNAVAILABLE THEN RETURN;
POKE(NOTB10,LISTEN);
ELF_ASLEEP_PRINTED←FALSE; ! make sure print out error ;
DO I←LISTENELF UNTIL I=LISTENING;
IF PSIZE>PBUFFSIZ THEN
ERROR("EVAL ERROR: statement pcode size too large");
POKEARRAY(PCDBUF+MAP_OFFSET,PSIZE,EXPR$:BODY[EE]);
POKE(NOTB10,WORK);
DO IF (I←LISTENELF)=GAVEUP
THEN BEGIN POKE(NOTB10,GOSLEEP);
ERROR("abandoned this instruction midway");
END UNTIL I=DONEWORKING;
PEEKARRAY(NOTB11,8,NOTBOX);
IF $INTSIZ←(INTPTR-INTBUF)/2 THEN
BEGIN
IF $INTSIZ<0 THEN ERROR("EVAL DISASTER: asking to transfer negative number of integers");
IF $INTSIZ>IBUFFSIZ THEN
ERROR("EVAL DISASTER: trying to transfer too many numbers; probably overran integer buffer");
PEEKARRAY(INTBUF+MAP_OFFSET,INTSIZ,$INBUF,SGNEXT);
END;
IF $FPSIZ←(FPPTR-FPBUF)/4 THEN
BEGIN
IF $FPSIZ<0 THEN ERROR("EVAL DISASTER: asking to transfer negative number of FP nums");
IF $FPSIZ>FBUFFSIZ THEN
ERROR("EVAL DISASTER: trying to transfer too many numbers; probably overran FP buffer");
! PEEKARRAY(FPBUF+MAP_OFFSET,FPSIZ,TMPBUF,TWLM);
PEEKARRAY(FPBUF+MAP_OFFSET,$FPSIZ*2,TTMPBUF);
FOR I←1 STEP 1 UNTIL $FPSIZ DO $FPBUF[I]←RFVAL(TTMPBUF[I*2-1],TTMPBUF[I*2]);
END;
POKE(NOTB10,GOSLEEP);
$FPPTR←$INTPTR←0;
$FPMAX←$FPMAX MAX $FPSIZ;
$INTMAX←$INTMAX MAX $INTSIZ;
END;
! routines that make console look like VT05;
PRELOAD_WITH 30,'2000/35,'2000/24,'2000/36,'2000/30,'2000/30;
INTEGER ARRAY LINWIDTH[0:MAX_TTY];
SIMPLE INTEGER PROCEDURE YPOS(INTEGER LINE);
RETURN('1000-LINE*LINWIDTH[$TTYTYPE]);
INTEGER ARRAY ADDR[0:'23];
SIMPLE INTEGER PROCEDURE LINEDPOS;
BEGIN
CALLU("PPINFO",ADDR[0]);
RETURN(ADDR[2]LAND '777777);
END;
DEFINE CONSOLE_PP="1"; ! pp 1 for the output of elf ;
DEFINE CONSOLE_MODE=0,VT05_MODE←-1;
DEFINE ELF_OREG='274 ;
DEFINE ELF_IREG='272 ;
DEFINE OUTSW='270;
REQUIRE "SYS:PROCES.DEF" SOURCE_FILE;
BOOLEAN $ELFINT;
SIMPLE PROCEDURE INTELF;
$ELFINT←TRUE;
ITEM READELF_ITEM,WRITEELF_ITEM,DUMMY_ITEM;
ITEMVAR MAINPR_ITEM;
REQUIRE 10 NEW_ITEMS;
PROCEDURE WRITEELF;
BEGIN INTEGER CHAR,VAL;
CHAR←0;
WHILE TRUE DO
BEGIN
WHILE (VAL←PEEK(ELF_IREG))≠0 DO URSCHD;
IF CHAR=CR THEN CHAR←INCHRW
ELSE BEGIN
WHILE (CHAR←INCHRS)<0 DO URSCHD;
IF (CHAR LAND '200) THEN CHAR←CHAR LAND '77;
POKE(ELF_IREG,CHAR);
END
END;
END;
DEFINE INTELF_INX=20;
PROCEDURE READELF;
BEGIN INTEGER CHAR;
WHILE TRUE DO
BEGIN
WHILE NOT $ELFINT DO URSCHD;
POLL;
$ELFINT←FALSE;
ENABLE(INTELF_INX);
CALLV("LEYPOS",LINEDPOS);
CALLV("PPSEL",'400000+CONSOLE_PP);
CHAR←PEEK(ELF_OREG);
POKE(ELF_OREG,0);
OUTCHR(CHAR);
CALLV("PPSEL",'400000);
END;
END;
PROCEDURE INIINTELF;
BEGIN
$ELFINT←FALSE;
intmap(INTELF_INX,INTELF,0); ! set mapping for interrupt handler for ELF;
enable(INTELF_INX); ! enable the interrupt handler;
END;
PROCEDURE ESCAPE_I;
BEGIN
DO URSCHD UNTIL $ESC_I;
TERMINATE(WRITEELF_ITEM);
TERMINATE(READELF_ITEM);
ENABLE(INTELF_INX);
RESUME(MAINPR_ITEM,DUMMY_ITEM,KILLME);
END;
INTERNAL PROCEDURE CONSOLE;
BEGIN ! makes this a console for output of 11 ;
MAINPR_ITEM←MYPROC;
POKE(OUTSW,VT05_MODE); ! clean out vt05 mode;
poke(elf_oreg,0);
INIINTELF;
POKE(OUTSW,CONSOLE_MODE); ! set to CONSOLE mode;
CALLV("PPSEL",'400000+CONSOLE_PP);
CALLV("DPYSIZ",15*'1000+1); ! 20 GLITCHES, 1 line per glitch ;
CALLV("DPYPOS",YPOS(3));
CALLV("PPACT",'400000 LOR ('400000 LSH -CONSOLE_PP));
SCHEDULE_ON_CLOCK_INTERRUPTS;
SPROUT(READELF_ITEM,READELF,RUNME);
CALLV("PPSEL",'400000);
CALLV("DPYPOS",YPOS(19));
CALLV("LEYPOS",LINEDPOS);
END;
INTERNAL PROCEDURE UNCONSOLE;
BEGIN
! change back to VT05;
TERMINATE(READELF_ITEM);
POKE(OUTSW,VT05_MODE);
DISABLE(INTELF_INX);
DISABLE(INTCLK_INX);
CALLV("PPREL",CONSOLE_PP);
END;
INTERNAL PROCEDURE VT05;
BEGIN INTEGER I;
! accepts input from the terminal;
IF PSTATUS(READELF_ITEM)=TERMINATED THEN CONSOLE;
SPROUT(WRITEELF_ITEM,WRITEELF,RUNME);
CALLV("LEYPOS",LINEDPOS);
I←'11000000200; ! turn on noecho bit ;
CALL(IOWD(1,LOCATION(I)+1),"TTYSET");
CALLV("PPSEL",'400000+CONSOLE_PP);
DO BEGIN URSCHD; CALL(1,"SLEEP"); END UNTIL $ESC_I;
$ESC_I←FALSE; ENABLE(INTTTI_INX);
CALLV("PPSEL",'400000);
TERMINATE(WRITEELF_ITEM);
I←'12000000200; ! turn off noecho bit ;
CALL(IOWD(1,LOCATION(I)+1),"TTYSET");
END;
! alinit;
INTERNAL PROCEDURE ALINIT;
BEGIN "init"
INTEGER COUNT, BRCHAR, EOF, FLAG;
INTEGER I;
! Initialize the ELF for output;
! '400 on in mode word and EOF←1 to take silent return if not available;
IF $NOELF OR $ELFUNAVAILABLE THEN RETURN;
EOF←1;
OPEN(ELFCHAN←GETCHAN,"ELF",'417,0,0,COUNT,BRCHAR,EOF);
IF EOF THEN
BEGIN PRINT("ELF is not available... I will just not do any i/o to ELF
"); $ELFUNAVAILABLE←TRUE; RETURN; END;
ELF_ASLEEP_PRINTED←FALSE;
MTAPE_PLUS_ELF←'072000000000+(ELFCHAN LSH 23);
END "init";
! sav11,res11;
INTERNAL PROCEDURE SAV11(INTEGER ARRAY MEM);
BEGIN
INTEGER I;
POKE(NOTB10,SAVE);
CALL(1,"SLEEP");
DO I←PEEK(NOTB11) UNTIL I=SAVED;
CALL(2,"SLEEP");
PEEKARRAY(0,ELFHIADDR/4,MEM,TWRJ);
END;
INTERNAL PROCEDURE RES11(INTEGER ARRAY MEM);
IF NOT($NOELF OR $ELFUNAVAILABLE) THEN
BEGIN
! commented out because cannot do packed mode write
POKEARRAY(0,'500000/4,MEM,TWRJ);
DEFINE BLKTRFR="(ELFHIADDR/(2*8))";! size of array transfer unpacked;
DEFINE UBLKTRFR="BLKTRFR/2"; ! size of array transfer packed;
INTEGER ARRAY TEMP[1:BLKTRFR];
INTEGER I,J,K; ! pointer to TEMP,MEM, and counter;
STRT11('130000); ! start ddt to bring system to rest;
! FILL; ! fill with zeroes ;
J←0;
FOR K←0 STEP 1 UNTIL 7
DO BEGIN
FOR I←2 STEP 2 UNTIL BLKTRFR
DO BEGIN
J←J+1;
TEMP[I-1]←(MEM[J] LSH -18) LAND '777777;
TEMP[I]←MEM[J] LAND '777777;
END;
POKEARRAY(K*BLKTRFR*2,BLKTRFR,TEMP);
END;
END;
INTERNAL PROCEDURE RESTRT11(INTEGER STRADR('1000));
BEGIN
INTEGER I;
IF $NOELF OR $ELFUNAVAILABLE THEN RETURN;
POKE(SAILID,"P");
POKE(OUTSW,VT05_MODE);
STRT11(STRADR);
DO I←LISTENELF UNTIL I=AWAKE;
PEEKARRAY(NOTB11,8,NOTBOX);
END;
END;